package pogvue.gui;

import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.io.*;
import java.awt.font.*;
import java.awt.geom.*;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

import pogvue.datamodel.*;
import pogvue.io.*;
import pogvue.gui.*;
import pogvue.gui.hub.*;
import pogvue.gui.event.*;
import pogvue.analysis.*;

public class LogoPanel extends JPanel {

  TFMatrix   matrix;
  Color[]    colors = new Color[4];
  
  int w = 200;
  int h = 70;
  
  boolean sizeByInfo = false;

  public LogoPanel(TFMatrix matrix) {
    this.matrix = matrix;
    
    colors[0] = Color.green.darker();
    colors[1] = Color.red.darker();
    colors[2] = Color.blue;
    colors[3] = Color.yellow.darker();
    
  }
  
  public AffineTransform getScaleTransform(float xscale, float yscale) {
    AffineTransform ascale = new AffineTransform();
    
    ascale.scale(xscale,yscale);
    
    return ascale;
  }
  public int drawLetter(Graphics2D g2,String s,Font font,Color c,FontRenderContext frc, int x, int y) {
    
    TextLayout        tstring = new TextLayout(s, font, frc);
    
	g2.setColor(c);
	tstring.draw(g2,x,y);
	
	float  yoff      = (float)tstring.getBounds().getHeight();

	return (int)yoff;
    }
    public Font scaleFont(Font font, float xval,float yval) {
	AffineTransform ascale = getScaleTransform(xval,yval);

	Font newfont = font.deriveFont(ascale);

	return newfont;
    }
	
    public void paintComponent(Graphics g) {

	double[] pwm = matrix.getPwm().getPwm();

	int len = pwm.length/4;

	String s      = "A";

	Graphics2D g2 = (Graphics2D)g;
	
	// Create fonts and text layouts
	
	FontRenderContext frc    = g2.getFontRenderContext();

	Font  font      = new Font("Times",Font.BOLD,40);

	// Scale the font to the right width and height

	TextLayout tstring = new TextLayout("A", font, frc);

	float      theight = (float)tstring.getBounds().getHeight();
	float      twidth  = (float)tstring.getBounds().getWidth();

	float xscale = (float)(25/twidth);
	float yscale = (float)((getSize().height - 10)/theight);
	
	//	Font tmpfont1 = scaleFont(font,xscale,yscale);

	//Font tmpfont2 = scaleFont(font,(float)1,(float)2);

	tstring = new TextLayout("A", font, frc);

	theight = (float)tstring.getBounds().getHeight();
	twidth  = (float)tstring.getBounds().getWidth();
	
	w = (int)(twidth*len + 20);
	h = (int)(theight + 10);

	g2.setColor(Color.white);
	g2.fillRect(0,0,w,h);

	
	for (int i = 0; i < len; i++) {

	    int charheight = 0;

	    // Get info content for this column  bases are in ATCG order
	    int ii  = 0;
	    double bit = 0;

	    while (ii < 4) {
		double pi = pwm[i*4+ii];

		if (pi > 0) {
		    bit += pi * Math.log(pi)/Math.log(2);

		}
		ii++;
	    }
	    
	    bit = 2+ bit;

	    ii = 0;

	    while (ii < 4) {
		String str = "A";

		if (ii == 1) { str = "T";}
		if (ii == 2) { str = "C";}
		if (ii == 3) { str = "G";}
		
		// Scale the info scaled font by pi and info

		float val = (float)(pwm[i*4+ii]);

		if (sizeByInfo == true) {
		  val = (float)(val*bit/2);
		}
		Font charfont    = scaleFont(font,(float)1,(float)(val));

		charheight      += drawLetter(g2,str,charfont,colors[ii],frc,(int)(10+i*twidth),h-charheight);

		ii++;
	    }
	}	    
    }

  public static TFMatrix stringToMatrix(String str) {
    
    // Matrices go like this

    // position 1    A   T   C   G
    // position 2    A   T   C   G

    // etc.  So for a string we'll have strlen rows,  and a 1 or a 0 in each of the positions

    int i = 0;

    double[][] out = new double[str.length()][4];
    char[]     arr = str.toCharArray();

    while (i < str.length()) {

      int j = 0;

      while (j < 4) {
	out[i][j] = 0;
	j++;
      }
      if (arr[i] == 'A') {
	out[i][0] = 1;
      } else if (arr[i] == 'T') {
	out[i][1] = 1;
      } else if (arr[i] == 'C') {
	out[i][2] = 1;
      } else if (arr[i] == 'G') {
	out[i][3] = 1;
      }
      i++;
    }

    TFMatrix strmat = new TFMatrix(out,str.length(),4);

    strmat.setName(str);

    return strmat;
  }

  public void setSizeByInfo(boolean sizeByInfo) {
    this.sizeByInfo = sizeByInfo;
  }
  public Dimension getMinimumSize() {
    return new Dimension(w,100);
  }
  public Dimension getPreferredSize() {
    return new Dimension(w,100);
  }

  public static void main(String[] args) {

    Vector fullmats  = null;
    Vector mats      = null;
    Vector matvect   = null;
    String seq = "GCTGCCACCGGGTGGCGCAA";

    TFMatrix ctcf    =  null;

    AlignViewport av = new AlignViewport(null,false,false,false,false);
      
    fullmats = av.getTransfacMatrices();
    
    if (mats == null) {
      mats    = new Vector();
      matvect = new Vector();
      
      for (int i = 0; i < fullmats.size(); i++) {
	TFMatrix tfm = (TFMatrix)fullmats.elementAt(i);
	
	if (tfm.getName().equals("CTCF_main")) {
	  ctcf = tfm;
	  matvect.addElement(tfm.getPwm());
	  mats.addElement(tfm);
	  
	}
      }
    }

    TFMatrix strmat = stringToMatrix(seq);

    System.out.println("Cons\t" + PwmCluster.getConsensus(strmat.getPwm().getPwm()));
    System.out.println("Cons\t" + PwmCluster.getConsensus(ctcf.getPwm().getPwm()));

    LogoPanel lp1 = new LogoPanel(ctcf);
    LogoPanel lp2 = new LogoPanel(strmat);

    JFrame jf = new JFrame("Logo test");

    jf.getContentPane().setLayout(new GridLayout(2,1));
    jf.getContentPane().add(lp1);
    jf.getContentPane().add(lp2);

    jf.setSize(400,400);
    jf.setVisible(true);
  }
}

	

